#include "CameraControl.h"

#include <windows.h>

CCameraControl::CCameraControl(void) {
	mEngine = CGameManager::getInstance();

	this->mRotationX = 0.0f;
    this->mRotationY = 0.0f;
    this->mDirection = core::vector3df(0,0,1);
	this->mAbsoluteDirection = core::vector3df(0,0,1);

	// default config settings
	this->mCameraLookSpeed = 100;
	this->mCameraMoveSpeed = 1000;

	this->mCamera = this->mEngine->getSceneManager()->addCameraSceneNode();
	this->mCamera->setPosition(vector3df(0,5000,5000));
	this->mCamera->setFarValue(300000);

	this->setSceneNode(this->mCamera);

	// add callbacks
	//this->registerCallbacks();
}
void CCameraControl::registerCallbacks() {
	//addEventT<CCameraControl>(this->mEngine->getEventManager(), EEVENT_TYPE::EET_MOUSE_INPUT_EVENT, this, &CCameraControl::onMouseClick, this);
}
CCameraControl::~CCameraControl(void)
{
}
void CCameraControl::update(f32 frameDelta) {
	IEventManager *er;

	er = this->mEngine->getEventManager();
	
// Right-click mouse look controls
	if(er->mouseClick(EMB_R)) {
		this->mEngine->getDevice()->getCursorControl()->setVisible(false);
		ShowCursor(false); // bugfix for retarded Irrlicht bug
		this->mEngine->getDevice()->getCursorControl()->setPosition(this->mEngine->getDevice()->getCursorControl()->getPosition());
	}
	if(er->mouseDown(EMB_R)) {
		this->turnRight(this->mCameraLookSpeed * (this->mEngine->getDevice()->getCursorControl()->getRelativePosition().X - 0.5f));
		this->turnUp(this->mCameraLookSpeed * (this->mEngine->getDevice()->getCursorControl()->getRelativePosition().Y - 0.5f));

		this->mEngine->getDevice()->getCursorControl()->setPosition(0.5f, 0.5f);
	}
	if(er->mouseUp(EMB_R)) {
		this->mEngine->getDevice()->getCursorControl()->setVisible(true);
		ShowCursor(true); // bugfix for retarded Irrlicht bug
		this->mEngine->getDevice()->getCursorControl()->setPosition(this->mEngine->getDevice()->getCursorControl()->getPosition());
	}

// Keyboard controls
	if(er->keyDown(KEY_KEY_W)) {
		this->move(vector3df(0,0,this->mCameraMoveSpeed * frameDelta));
	}
	if(er->keyDown(KEY_KEY_S)) {
		this->move(vector3df(0,0,-this->mCameraMoveSpeed * frameDelta));
	}
	if(er->keyDown(KEY_KEY_A)) {
		this->move(vector3df(-this->mCameraMoveSpeed * frameDelta,0,0));
	}
	if(er->keyDown(KEY_KEY_D)) {
		this->move(vector3df(this->mCameraMoveSpeed * frameDelta,0,0));
	}

}
void CCameraControl::move(vector3df vel) {
	matrix4 matrix;
	matrix.setRotationDegrees(vector3df(this->mRotationX, this->mRotationY, 0));
    matrix.rotateVect(vel);
    
    this->mCamera->setPosition(this->mCamera->getPosition() + vel);
    this->mCamera->setTarget(this->mCamera->getPosition() + this->mDirection);

    this->mCamera->updateAbsolutePosition();
}
void CCameraControl::setPosition(vector3df pos)
{
	this->mCamera->setPosition(pos);
	this->mCamera->updateAbsolutePosition();
}
void CCameraControl::turnRight(f32 i)
{
	this->mRotationY += i;
	if(this->mRotationY>=360)this->mRotationY-=360;
	if(this->mRotationY<0)this->mRotationY+=360;

	this->mDirection = core::vector3df(0,0,1);

	core::matrix4 matrix;
	matrix.setRotationDegrees(core::vector3df (this->mRotationX,this->mRotationY,0));
	matrix.rotateVect(this->mDirection);

	this->mCamera->setTarget(this->mCamera->getPosition() + this->mDirection);
	this->mCamera->updateAbsolutePosition();
}

void CCameraControl::turnLeft(f32 i)
{
	this->mRotationY -= i;
	if(this->mRotationY>=360)this->mRotationY-=360;
	if(this->mRotationY<0)this->mRotationY+=360;

	this->mDirection = core::vector3df(0,0,1);

	core::matrix4 matrix;
	matrix.setRotationDegrees(core::vector3df (this->mRotationX,this->mRotationY,0));
	matrix.rotateVect(this->mDirection);

	this->mCamera->setTarget(this->mCamera->getPosition() + this->mDirection);
	this->mCamera->updateAbsolutePosition();
}

void CCameraControl::turnUp(f32 i)
{
	this->mRotationX += i;
	if(this->mRotationX>=360)this->mRotationX-=360;
	if(this->mRotationX<0)this->mRotationX+=360;

	this->mDirection = core::vector3df(0,0,1);

	core::matrix4 matrix;
	matrix.setRotationDegrees(core::vector3df (this->mRotationX,this->mRotationY,0));
	matrix.rotateVect(this->mDirection);

	this->mCamera->setTarget(this->mCamera->getPosition() + this->mDirection);
	this->mCamera->updateAbsolutePosition();
}

void CCameraControl::turnDown(f32 i)
{
	this->mRotationX -= i;
	if(this->mRotationX>=360)this->mRotationX-=360;
	if(this->mRotationX<0)this->mRotationX+=360;

	this->mDirection = core::vector3df(0,0,1);

	core::matrix4 matrix;
	matrix.setRotationDegrees(core::vector3df (this->mRotationX,this->mRotationY,0));
	matrix.rotateVect(this->mDirection);

	this->mCamera->setTarget(this->mCamera->getPosition() + this->mDirection);
	this->mCamera->updateAbsolutePosition();
}

